home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / lib / c / syscall / proc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-03-27  |  6.2 KB  |  233 lines

  1. /* 
  2.  * proc.c --
  3.  *
  4.  *    Miscellaneous run-time library routines for the Proc module.
  5.  *
  6.  * Copyright 1986 Regents of the University of California
  7.  * All rights reserved.
  8.  */
  9.  
  10. #ifndef lint
  11. static char rcsid[] = "$Header: /sprite/src/lib/c/syscall/RCS/proc.c,v 1.7 90/01/03 17:30:48 douglis Exp $ SPRITE (Berkeley)";
  12. #endif not lint
  13.  
  14. #include <sprite.h>
  15. #include <status.h>
  16. #include <proc.h>
  17. #include <stdio.h>
  18.  
  19.  
  20. /*
  21.  *----------------------------------------------------------------------
  22.  *
  23.  * Proc_Exec --
  24.  *
  25.  *    Maps Proc_Exec calls into Proc_ExecEnv calls.  This routine
  26.  *    should not return unless the process cannot be exec'ed.
  27.  *
  28.  *
  29.  * Results:
  30.  *    Error status from Proc_ExecEnv, if any.
  31.  *
  32.  * Side effects:
  33.  *    Refer to Proc_ExecEnv kernel call & man page.
  34.  *
  35.  *----------------------------------------------------------------------
  36.  */
  37.  
  38. int
  39. Proc_Exec(fileName, argPtrArray, debugMe)
  40.     char *fileName;
  41.     char **argPtrArray;
  42.     Boolean debugMe;
  43. {
  44.     int status;
  45.     extern char **environ;
  46.     extern char **Proc_FetchGlobalEnv();    /* temporary!! */
  47.  
  48.     /*
  49.      * Install the system-wide environment if ours is non-existent.
  50.      */
  51.     if (environ == (char **) NULL) {
  52.     environ = Proc_FetchGlobalEnv();
  53.     }
  54.     status = Proc_ExecEnv(fileName, argPtrArray, environ, debugMe);
  55.     return(status);
  56. }
  57.  
  58. /*
  59.  *----------------------------------------------------------------------
  60.  *
  61.  * Proc_Wait --
  62.  *
  63.  *    The "normal" interface for waiting on child processes.
  64.  *    This procedure simply invokes the Proc_RawWait system call
  65.  *    and retries the call if the Proc_RawWait call aborted because
  66.  *    of a signal.  See the man page for details on what the kernel
  67.  *    call does.
  68.  *
  69.  * Results:
  70.  *    A standard Sprite return status.
  71.  *
  72.  * Side effects:
  73.  *    None.
  74.  *
  75.  *----------------------------------------------------------------------
  76.  */
  77.  
  78. ReturnStatus
  79. Proc_Wait(numPids, pidArray, block, procIdPtr, reasonPtr, statusPtr,
  80.     subStatusPtr, usagePtr)
  81.     int numPids;        /* Number of entries in pidArray below.
  82.                  * 0 means wait for ANY child. */
  83.     int pidArray[];        /* Array of pids to wait for. */
  84.     Boolean block;        /* TRUE means block;  FALSE means return
  85.                  * immediately if no children are dead. */
  86.     int *procIdPtr;        /* Return ID of dead/stopped process here,
  87.                  * if non-NULL. */
  88.     int *reasonPtr;        /* Return cause of death/stoppage here, if
  89.                  * non-NULL. */
  90.     int *statusPtr;        /* If process exited normally, return exit
  91.                  * status here (if non-NULL).  Otherwise
  92.                  * return signal # here. */
  93.     int *subStatusPtr;        /* Return additional signal status here,
  94.                  * if non-NULL. */
  95.     Proc_ResUsage *usagePtr;    /* Return resource usage info here,
  96.                  * if non-NULL. */
  97. {
  98.     ReturnStatus status;
  99.  
  100.     do {
  101.     status = Proc_RawWait(numPids, pidArray, block, procIdPtr,
  102.         reasonPtr, statusPtr, subStatusPtr, usagePtr);
  103.     } while (status == GEN_ABORTED_BY_SIGNAL);
  104.     return status;
  105. }
  106.  
  107.  
  108. /*
  109.  *----------------------------------------------------------------------
  110.  *
  111.  * Proc_Migrate --
  112.  *
  113.  *    The "normal" interface for invoking process migration.  This
  114.  *    performs extra checks against the process being migrated when
  115.  *    it is already migrated to a different machine.  
  116.  *
  117.  * Results:
  118.  *    A standard Sprite return status.
  119.  *
  120.  * Side effects:
  121.  *    The process is migrated home if it is not already home, then
  122.  *    it is migrated to the node specified.
  123.  *
  124.  *----------------------------------------------------------------------
  125.  */
  126.  
  127. ReturnStatus
  128. Proc_Migrate(pid, nodeID)
  129.     Proc_PID pid;
  130.     int         nodeID;
  131. {
  132.     ReturnStatus status;
  133.     int virtualHost;
  134.     int physicalHost;
  135.  
  136.     status = Proc_GetHostIDs(&virtualHost, &physicalHost);
  137.     if (status != SUCCESS) {
  138.     return(status);
  139.     }
  140.     if (pid == PROC_MY_PID) {
  141.     if (nodeID != physicalHost && nodeID != virtualHost) {
  142.         status = Sig_Send(SIG_MIGRATE_HOME, PROC_MY_PID, FALSE);
  143.         if (status != SUCCESS) {
  144.         return(status);
  145.         }
  146.     }
  147.     } else {
  148.     int i;
  149.     Proc_PCBInfo info;
  150.     /*
  151.      * Try to avoid the race condition for migrating other processes
  152.      * home.  This can be removed once the kernel does remote-to-remote
  153.      * migration directly.
  154.      */
  155. #define WAIT_MAX_TIMES 10
  156. #define WAIT_INTERVAL 1
  157.     (void) Sig_Send(SIG_MIGRATE_HOME, pid, TRUE);
  158.     for (i = 0; i < WAIT_MAX_TIMES; i++) {
  159.         status = Proc_GetPCBInfo(Proc_PIDToIndex(pid),
  160.                      Proc_PIDToIndex(pid), PROC_MY_HOSTID,
  161.                      sizeof(info),
  162.                      &info, (char *) NULL , (int *) NULL);
  163.         if (status != SUCCESS) {
  164.         return(status);
  165.         }
  166.         if (info.state != PROC_MIGRATED) {
  167.         break;
  168.         }
  169.         (void) sleep(WAIT_INTERVAL);
  170.     }
  171.     if (i == WAIT_MAX_TIMES) {
  172.         fprintf(stderr, "Unable to migrate process %x because it wouldn't migrate home.\n", pid);
  173.         return(FAILURE);
  174.     }
  175.     }
  176.     status = Proc_RawMigrate(pid, nodeID);
  177.     return(status);
  178. }
  179.  
  180. /*
  181.  *----------------------------------------------------------------------
  182.  *
  183.  * Proc_RemoteExec --
  184.  *
  185.  *    The "normal" interface for invoking remote exec.  This
  186.  *    performs extra checks against the process being migrated when
  187.  *    it is already migrated to a different machine.  
  188.  *
  189.  * Results:
  190.  *    This routine does not return if it succeeds.
  191.  *    A standard Sprite return status is returned upon failure.
  192.  *
  193.  * Side effects:
  194.  *    The process is migrated home if it is not already home, then
  195.  *    a remote exec is performed.
  196.  *
  197.  *----------------------------------------------------------------------
  198.  */
  199.  
  200. ReturnStatus
  201. Proc_RemoteExec(fileName, argPtrArray, envPtrArray, host)
  202.     char    *fileName;    /* The name of the file to exec. */
  203.     char    **argPtrArray;    /* The array of arguments to the exec'd 
  204.                  * program. */
  205.     char    **envPtrArray;    /* The array of environment variables for
  206.                  * the exec'd program. */
  207.     int        host;        /* ID of host on which to exec. */
  208. {
  209.     ReturnStatus status;
  210.     int virtualHost;
  211.     int physicalHost;
  212.  
  213.     status = Proc_GetHostIDs(&virtualHost, &physicalHost);
  214.     if (status != SUCCESS) {
  215.     return(status);
  216.     }
  217.     /*
  218.      * Save a double migration if the exec is local.
  219.      */
  220.     if (physicalHost != host) {
  221.     if (virtualHost != host) {
  222.         status = Sig_Send(SIG_MIGRATE_HOME, PROC_MY_PID, FALSE);
  223.         if (status != SUCCESS) {
  224.         return(status);
  225.         }
  226.     }
  227.     status = Proc_RawRemoteExec(fileName, argPtrArray, envPtrArray, host);
  228.     } else {
  229.     status = Proc_Exec(fileName, argPtrArray, envPtrArray, FALSE);
  230.     }
  231.     return(status);
  232. }
  233.